package model.uml.note;

import java.beans.PropertyChangeListener;
import java.util.List;

import javax.xml.bind.annotation.XmlTransient;

import util.CollectionChangeEvent;
import util.CollectionChangeListener;
import util.CollectionChangeSupport;

import model.AbstractStatechartComponent;
import model.util.Dimension;
import model.util.Point;

public class Note extends AbstractStatechartComponent {

	public static final Dimension DEFAULT_SIZE = new Dimension(100f, 100f);

	private String text;
	private Dimension size = DEFAULT_SIZE;
	private List<NoteLink> noteLinks;

	@XmlTransient
	private CollectionChangeSupport<NoteLink> noteLinkCollectionChangeSupport = new CollectionChangeSupport<NoteLink>(
			this);

	public enum Property {
		DIMENSION, TEXT, NOTELINKS
	};

	// creation in app
	public Note(long id, Long parentId, Point location) {
		super(id, parentId, location);
	}

	// creation from file
	public Note(Long id, Long parentId, Point location, Dimension size,
			String text) {
		super(id, parentId, location);
		this.size = size;
		this.text = text;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		String oldText = this.text;
		this.text = text;
		propertyChangeSupport.firePropertyChange(Property.TEXT.name(), oldText,
				text);
	}

	public Dimension getSize() {
		return size;
	}

	public void setSize(Dimension size) {
		Dimension oldSize = this.size;
		this.size = size;
		propertyChangeSupport.firePropertyChange(Property.DIMENSION.name(),
				oldSize, size);
	}

	public List<NoteLink> getNoteLinks() {
		return noteLinks;
	}

	public void setNoteLinks(List<NoteLink> noteLinks) {
		List<NoteLink> oldNoteLinks = this.noteLinks;
		this.noteLinks = noteLinks;
		propertyChangeSupport.firePropertyChange(Property.NOTELINKS.name(),
				oldNoteLinks, noteLinks);
		this.noteLinks = noteLinks;
	}

	public void addNoteLink(NoteLink noteLink) {
		if (!this.noteLinks.contains(noteLink)) {
			this.noteLinks.add(noteLink);
			this.noteLinkCollectionChangeSupport.fireCollectionChanged(
					noteLink, noteLinks.indexOf(noteLink),
					CollectionChangeEvent.Type.ADD);
		}
	}

	public void removeNoteLink(NoteLink noteLink) {
		if (this.noteLinks.contains(noteLink)) {
			int index = noteLinks.indexOf(noteLink);
			this.noteLinks.remove(noteLink);
			this.noteLinkCollectionChangeSupport.fireCollectionChanged(
					noteLink, index, CollectionChangeEvent.Type.REMOVE);
		}
	}

	public void addNoteLinkCollectionChangeListener(
			CollectionChangeListener<NoteLink> listener) {
		this.noteLinkCollectionChangeSupport.addCollectionListener(listener);
	}

	public void removeNoteLinkCollectionChangeListener(
			CollectionChangeListener<NoteLink> listener) {
		this.noteLinkCollectionChangeSupport.removeCollectionListener(listener);
	}

	public void addPropertyChangeListener(Property property,
			PropertyChangeListener listener) {
		this.propertyChangeSupport.addPropertyChangeListener(property.name(),
				listener);
	}

	public void removePropertyChangeListener(Property property,
			PropertyChangeListener listener) {
		this.propertyChangeSupport.removePropertyChangeListener(
				property.name(), listener);
	}

	@Override
	public String toString() {
		return "Note [id= " + id + ", location=" + location + ", size=" + size
				+ ", text=" + text + "]";
	}

}
